/* $RCSFile: Text2Image.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/Helpers/Text2Image.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:28  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;

using AddonNice.Diagnostics;

namespace AddonNice.Helpers
{
	public class Text2Image
	{
		#region Private Variables
		private string _FontFace		=	"Verdana";
		private int _FontSize			=	8;
		private Color _FontColor		=	Color.Black;
		private FontStyle _FontStyle	=	FontStyle.Regular;
		private Color _BackgroundColor	=	Color.White;
		bool _isTransparent				=	true;
		#endregion
		
		#region Public Properties
		
		/// <summary>
		/// Get/Set backColor, default: white
		/// </summary>
		public Color BackGroundColor
		{
			get { return _BackgroundColor; }
			set { _BackgroundColor = value; }
		}

		/// <summary>
		/// Get/Set font color, default: black
		/// </summary>
		public Color FontColor
		{
			get { return _FontColor; }
			set { _FontColor = value; }
		}
		/// <summary>
		/// Get/Set font size, default 8
		/// </summary>
		public int FontSize
		{
			get { return _FontSize; }
			set { _FontSize = value; }
		}
		/// <summary>
		/// Get/Set font Face, default verdana
		/// </summary>
		public string FontFace
		{
			get { return _FontFace; }
			set { _FontFace = value; }
		}
		
		/// <summary>
		/// Get/Set font style, default regular
		/// </summary>
		public FontStyle FontStyle
		{
			get { return _FontStyle; }
			set { _FontStyle = value; }
		}
		
		
		/// <summary>
		/// Should the background color bemarked as transparent
		/// </summary>
		public bool isTransparent 
		{
			get { return _isTransparent ; }
			set { _isTransparent  = value; }
		}
		
		#endregion
		
		#region Constructor
		public Text2Image() { }
		#endregion

        Bitmap MakeTransparent(MemoryStream origBitmapMemoryStream, Color transparentColor)
        {

            Bitmap origBitmap = new Bitmap(origBitmapMemoryStream);
            int transparentArgb = transparentColor.ToArgb();
			if ( CoreTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"Text2Image MakeTransparent origBitmap.Width: {0}, origBitmap.Height: {1}, transparentArgb: {2}",new object[]{origBitmap.Width, origBitmap.Height,transparentArgb}),CoreTraceSwitch.Sw.Info);

            using (Bitmap newBitmap = new Bitmap(origBitmap.Width, origBitmap.Height, /*origBitmap.PixelFormat*/PixelFormat.Format8bppIndexed ))
            {

                ColorPalette origPalette = origBitmap.Palette;
                ColorPalette newPalette = newBitmap.Palette;

                int index = 0;
                int transparentIndex = -1;

			    if ( CoreTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"Text2Image MakeTransparent origPalette.Entries: {0}",origPalette.Entries.GetLength(0)),CoreTraceSwitch.Sw.Info);
                foreach (Color origColor in origPalette.Entries)
                {
                    newPalette.Entries[index] = Color.FromArgb(255, origColor);
                    if (origColor.ToArgb() == transparentArgb) 
                        transparentIndex = index;
                    index += 1;
                }

		        if ( CoreTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"Text2Image MakeTransparent transparentIndex: {0}",transparentIndex),CoreTraceSwitch.Sw.Info);
                if (-1 == transparentIndex)
                {
                    return origBitmap;
                }

                newPalette.Entries[transparentIndex] = Color.FromArgb(0, transparentColor);
                newBitmap.Palette = newPalette;

                Rectangle rect = new Rectangle(0, 0, origBitmap.Width, origBitmap.Height);

                BitmapData origBitmapData = origBitmap.LockBits(rect, ImageLockMode.ReadOnly, origBitmap.PixelFormat);
                BitmapData newBitmapData = newBitmap.LockBits(rect, ImageLockMode.WriteOnly, newBitmap.PixelFormat);

                for (int y = 0; y < origBitmap.Height; y++)
                {
                    for (int x = 0; x < origBitmap.Width; x++)
                    {
                        byte origBitmapByte = Marshal.ReadByte(origBitmapData.Scan0, origBitmapData.Stride * y + x);
                        Marshal.WriteByte(newBitmapData.Scan0, newBitmapData.Stride * y + x, origBitmapByte);
                    }
                }

                newBitmap.UnlockBits(newBitmapData);
                origBitmap.UnlockBits(origBitmapData);

                MemoryStream m = new MemoryStream();
                newBitmap.Save(m, ImageFormat.Gif);
                return new Bitmap(m);

            }
        }

        /// <summary>
		/// Creates a bitmap in the box sent (2 pix added), colors it with backgroup color and draws the text 
		/// with fontStyle, FontName and FontColor
		/// </summary>
		/// <param name="Text"></param>
		/// <param name="Sf"></param>
		/// <returns></returns>
		public Bitmap MakeImage(string Text, SizeF Sf)
		{
			int width				= (int)(Sf.Width)+2;
			int height				= (int)(Sf.Height)+2;

			if ( CoreTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"Text2Image MakeImage text: {0}, width: {1}, height: {2}, isTranspaent: {3}, backColor: {4}",new object[]{Text,width,height,isTransparent,_BackgroundColor}),CoreTraceSwitch.Sw.Info);

            Bitmap imageObj			= new Bitmap(width, height);
			Graphics graphicsObj	= Graphics.FromImage(imageObj);

			// Create a border in the color of the font
			//graphicsObj.FillRectangle(new SolidBrush(_FontColor), 0, 0, width, height);
			// Create a LightBlue background
			graphicsObj.FillRectangle(new SolidBrush(_BackgroundColor), 0, 0, width, height);

			// Specify the font and alignment
			Font fontBanner			= new Font(_FontFace, _FontSize, _FontStyle );

			// center align the advertising pitch
			StringFormat stringFormat	= new StringFormat();
			stringFormat.Alignment		= StringAlignment.Center;
			stringFormat.LineAlignment	= StringAlignment.Center;

			// Draw the adverising pitch
			graphicsObj.DrawString(Text, fontBanner, new SolidBrush(_FontColor), new Rectangle(0, 0, width, height), stringFormat);

			// Force graphicsObj to release its resources, namely imageObj .  
			graphicsObj.Dispose();

            if (isTransparent)
            {
                MemoryStream m = new MemoryStream();
                imageObj.Save(m, ImageFormat.Gif);
                return MakeTransparent(m, _BackgroundColor);
            }

			return imageObj;
		}

		/// <summary>
		/// Get the box necessary to write the text sent with parameter set for the object
		/// </summary>
		/// <param name="mystring"></param>
		/// <returns></returns>
		public SizeF CheckWidth(string mystring)
		{
			Bitmap b			=	null;
			Graphics g			=	null;
			SizeF CurrentWidth	=	new SizeF(0, 0);
			try
			{
				Font menuFont	=	new Font(_FontFace, _FontSize, _FontStyle);
				b				=	new Bitmap(12, 12);
				g				=	Graphics.FromImage(b);
				CurrentWidth	=	g.MeasureString(mystring, menuFont);
				if ( CoreTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"Text2Image CheckWidth CurrentWidth {0},{1}",CurrentWidth.Width,CurrentWidth.Height),CoreTraceSwitch.Sw.Info);
			}
			finally
			{
				if (g != null)
					g.Dispose();
				if (b != null)
					b.Dispose();
			}
			return CurrentWidth;
		}

		
		/// <summary>
		/// Calculate the default size,
		/// Creates a bitmap in the box sent (2 pix added), colors it with backgroup color and draws the text 
		/// with fontStyle, FontName and FontColor
		/// </summary>
		public Bitmap MakeImage(string Text)
		{
			return MakeImage(Text,CheckWidth(Text));
		}
    }
}
